package entity

import (
	"database/sql"
	"github.com/astaxie/beego/orm"
	"github.com/gomodule/redigo/redis"
	"nspel/nspel"
	"strconv"
	"time"
)

type Student struct {
	Id               int64          `orm:"pk;auto;column(id)"`
	CountryId        int64          `orm:"column(country_id)"`
	ProvinceId       int64          `orm:"column(province_id)"`
	CityId           int64          `orm:"column(city_id)"`
	AreaId           int64          `orm:"column(area_id)"`
	ExperimentAreaId int64          `orm:"column(experiment_area_id)"`
	SchoolId         int64          `orm:"column(school_id)"`
	Name             string         `orm:"column(name)"`
	SchoolRollId     string         `orm:"column(school_roll_id)"`
	CurrentGrade     string         `orm:"column(current_grade)"`
	CurrentClass     string         `orm:"column(current_class)"`
	Sex              byte           `orm:"column(sex)"`
	Birthday         time.Time      `orm:"column(birthday)"`
	IdentityId       sql.NullString `orm:"column(identity_id)"`
	Nation           string         `orm:"column(nation)"`
	Phone            sql.NullString `orm:"column(phone)"`
	Address          sql.NullString `orm:"column(address)"`
	Password         sql.NullString `orm:"column(password)"`
	WechatOpenId     sql.NullString `orm:"column(wechat_openid)"`
	QqOpenId         sql.NullString `orm:"column(qq_openid)"`
	StudentId        string         `orm:"column(student_id)"`
	CreatedAt        time.Time      `orm:"auto_now_add;column(created_at)"`
	UpdatedAt        time.Time      `orm:"auto_now;column(updated_at)"`
}

func init() {
	orm.RegisterModel(new(Student))
}

func (*Student) TableName() string {
	return "student"
}

func (s *Student) SelectAllBySchoolRollId(schoolRollId string) error {
	s.SchoolRollId = schoolRollId
	key := "student"
	hashKey := "schoolRollId[\"" + schoolRollId + "\"]"
	err := nspel.RedisHgetJson(key, hashKey, s)
	if err == nil {
		return nil
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	err = nspel.GetOrmEngine().Read(s, "school_roll_id")
	if err != nil {
		return err
	}
	nspel.RedisHsetJson(key, hashKey, s)
	return nil
}

func (s *Student) Insert() error {
	_, err := nspel.GetOrmEngine().Insert(s)
	return err
}

func (s *Student) Update(columns ...string) error {
	_, err := nspel.GetOrmEngine().Update(s, columns...)
	return err
}

func (s *Student) ImportInsert() error {
	err := s.Insert()
	return err
}

func (s *Student) ImportUpdate() error {
	err := s.Update("country_id", "province_id", "city_id", "area_id", "experiment_area_id", "school_id", "name", "current_grade", "current_class", "sex", "birthday", "identity_id", "nation", "student_id")
	return err
}

func (s *Student) SelectCountBySchoolId(schoolId int64) (int64, error) {
	key := "student"
	hashKey := "schoolId[" + strconv.FormatInt(schoolId, 10) + "].count"
	count, err := nspel.RedisHgetInt64(key, hashKey)
	if err == nil {
		return int64(count), nil
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	count, err = nspel.GetOrmEngine().QueryTable(s.TableName()).Filter("school_id", schoolId).Count()
	if err != nil {
		return 0, err
	}
	nspel.RedisHsetInt64(key, hashKey, count)
	return int64(count), nil
}

func (s *Student) CustomCount(ormEng *orm.QuerySeter, hashKey string) (count int64, err error) {
	key := "student"
	count, err = nspel.RedisHgetInt64(key, hashKey)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	count, err = (*ormEng).Count()
	if err != nil {
		return
	}
	nspel.RedisHsetInt64(key, hashKey, count)
	return
}

func (s *Student) CustomSelectAll(ormEng *orm.QuerySeter, hashKey string) (students []Student, err error) {
	key := "student"
	err = nspel.RedisHgetJson(key, hashKey, &students)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	_, err = (*ormEng).All(&students)
	if err != nil {
		return
	}
	nspel.RedisHsetJson(key, hashKey, students)
	return
}

func (s *Student) SelectAllById(id int64) (err error) {
	key := "student"
	hashKey := "id[" + strconv.FormatInt(id, 10) + "]"
	err = nspel.RedisHgetJson(key, hashKey, s)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	s.Id = id
	err = nspel.GetOrmEngine().Read(s)
	if err != nil {
		return
	}
	nspel.RedisHsetJson(key, hashKey, s)
	return
}

func (s *Student) SelectAllByPhone(phone string) (err error) {
	key := "student"
	hashKey := "phone[" + phone + "]"
	err = nspel.RedisHgetJson(key, hashKey, s)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	s.Phone = sql.NullString{String: phone, Valid: true}
	err = nspel.GetOrmEngine().Read(s, "phone")
	if err != nil {
		return
	}
	nspel.RedisHsetJson(key, hashKey, s)
	return
}

func (s *Student) DeleteById(id int64) (err error) {
	s.Id = id
	_, err = nspel.GetOrmEngine().Delete(s)
	return err
}
